#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "cashplusplus.h"
#include "logindialog.h"
#include "createdialog.h"

MainWindow::MainWindow(QWidget *parent) :
	QMainWindow(parent),
	m_ui(new Ui::MainWindow)
{
	m_ui->setupUi(this);

	connect(m_ui->startScreen, SIGNAL(loadAccountPressed()), this, SLOT(slot_loadAccountPressed()));
	connect(m_ui->startScreen, SIGNAL(newAccountPressed()), this, SLOT(slot_newAccountPressed()));

	connect(m_ui->actionE_xit, SIGNAL(triggered()), this, SLOT(close()));

	QShortcut* close_window = new QShortcut(QKeySequence::Close, this);
	connect(close_window, SIGNAL(activated()), this, SLOT(close()));

	m_ui->stackedWidget->setCurrentIndex(START);

	m_login = 0;
}

MainWindow::~MainWindow()
{
	delete m_ui;
}

void MainWindow::showCreateDialog(const QString& netID, const QString& filename)
{
	m_loginMode = CREATE;

	CreateDialog create(netID, filename, this);

	if (create.exec())
	{
		cleanup();

		QString netID = create.netID();
		QString password = create.password();
		m_filename = create.filename();

		if (m_filename == "")
		{
			showCreateDialog(netID, m_filename);
		}
		else
		{
			login(netID, password);
		}
	}
}

void MainWindow::loadDatabase()
{
	m_loginMode = LOAD;
	QString * filter = new QString("Cash++ account groups (*.cash);;All files (*.*)");
	m_filename = QFileDialog::getOpenFileName(this, tr("Choose Account Group to load"),  QString(), (*filter), filter);

	if (m_filename != "")
	{
		cleanup();

		QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", CashPlusPlus::DB_NAME);
		db.setDatabaseName(m_filename);

		if (!db.open())
		{
			QMessageBox::critical(this, "File Load Error", (tr("Could not open the specified file!")));
			m_ui->stackedWidget->setCurrentIndex(START);
			return;
		}

		QSqlQuery q(db);

		if (q.exec("SELECT netid, version FROM info"))
		{
			q.next();
			QString netID = q.value(0).toString();
			int version = q.value(1).toInt();

			if (version != CashPlusPlus::VERSION)
			{
				QMessageBox::critical(this, "Incompatible version", "The file you have tried to open is not compatible with Cash++");
			}
			else
			{
				LoginDialog loginbox(netID, this);

				if(loginbox.exec() == QDialog::Accepted)
				{
					QString password = loginbox.password();

					login(netID, password);
				}
			}
		}
		else
		{
			QMessageBox::critical(this, "Incompatible version", "The file you have tried to open is not compatible with Cash++");
		}
	}
}

void MainWindow::slot_loadAccountPressed()
{
	loadDatabase();
}

void MainWindow::slot_newAccountPressed()
{
	showCreateDialog();
}

void MainWindow::cleanup()
{
	m_ui->transactionsWidget->cleanup();
	m_ui->manageAccountsWidget->cleanup();

	QSqlDatabase::database(CashPlusPlus::DB_NAME).close();
	QSqlDatabase::removeDatabase(CashPlusPlus::DB_NAME);

	m_ui->action_Update_ND_accounts->setDisabled(true);
}

void MainWindow::login(const QString& netID, const QString& password)
{
	if (m_login)
	{
		m_login->deleteLater();
	}

	m_login = new NDLogin(netID);

	connect(m_login, SIGNAL(loginSuccess(QString)), this, SLOT(slot_loginSuccess(QString)));
	connect(m_login, SIGNAL(loginFailure()), this, SLOT(slot_loginFailure()));
	connect(m_login, SIGNAL(httpError(QString)), this, SLOT(slot_httpError(QString)));

	connect(m_login, SIGNAL(gotTransactions(QList<QStringList>)), m_ui->transactionsWidget, SLOT(slot_updateNDTransactions(QList<QStringList>)));
	connect(m_login, SIGNAL(gotBalances(double, double)), m_ui->manageAccountsWidget, SLOT(slot_updateNDBalances(double,double)));

	m_login->login(password);
}

void MainWindow::on_actionClose_Account_Group_triggered()
{
	cleanup();
	m_ui->stackedWidget->setCurrentIndex(START);
}

void MainWindow::on_action_Update_ND_accounts_triggered()
{
	if (m_login)
	{
		m_ui->transactionsWidget->flushData();
		m_ui->manageAccountsWidget->flushData();
		m_login->getTransactions();
	}
}

void MainWindow::slot_loginSuccess(const QString& name)
{
	setWindowTitle("Cash++ | Accounts for " + name);

	if (m_loginMode == CREATE)
	{
		QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", CashPlusPlus::DB_NAME);
		db.setDatabaseName(m_filename);

		if (!db.open())
		{
			// TODO report what happened
			showCreateDialog(m_login->netID(), m_filename);
			return;
		}
		else
		{
			// Get rid of everything
			QSqlQuery q = QSqlQuery(db);
			q.exec("DROP TABLE IF EXISTS info");
			q.exec("DROP TABLE IF EXISTS transactions");
			q.exec("DROP TABLE IF EXISTS accounts");
			q.exec("DROP TABLE IF EXISTS account_types");
			q.exec("VACUUM");

			// Create the necessary tables
			q.exec("CREATE TABLE info (netID TEXT PRIMARY KEY, version INTEGER)");
			q.exec("CREATE TABLE transactions (id INTEGER PRIMARY KEY AUTOINCREMENT, account_id INTEGER, amount REAL, datetime INTEGER, category TEXT, description TEXT)");
			q.exec("CREATE TABLE accounts (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, type INTEGER, amount REAL)");
			q.exec("CREATE TABLE account_types (id INTEGER PRIMARY KEY, name TEXT)");

			// Set up info table
			q.prepare("INSERT INTO info VALUES (?, ?)");
			q.addBindValue(m_login->netID());
			q.addBindValue(CashPlusPlus::VERSION);
			q.exec();

			q.prepare("INSERT INTO account_types VALUES (?, ?)");
			QVariantList ids, names;
			ids << CashPlusPlus::CASH << CashPlusPlus::FLEX << CashPlusPlus::DOMER << CashPlusPlus::BANK << CashPlusPlus::OTHER;
			names << "Cash" << "Flex Points" << "Domer Dollars" << "Bank" << "Other";
			q.addBindValue(ids);
			q.addBindValue(names);
			q.execBatch();

			q.finish();
		}
	}

	m_ui->transactionsWidget->initializeModel();
	m_ui->manageAccountsWidget->initializeModel();
	m_ui->graphWidget->initializeModel();
	m_ui->stackedWidget->setCurrentIndex(TABS);
	m_ui->tabWidget->setCurrentIndex(0);

	//Enable the Update item in the menubar
	m_ui->action_Update_ND_accounts->setEnabled(true);
}

void MainWindow::slot_loginFailure()
{
	if (m_loginMode == CREATE)
	{
		// TODO report what happened
		showCreateDialog(m_login->netID(), m_filename);
	}
	else
	{
		QMessageBox::critical(this, "Login Error", (tr("Login error: Incorrect username/password or NDFS account not found")));
		m_ui->stackedWidget->setCurrentIndex(START);
	}
}

void MainWindow::slot_httpError(const QString& error)
{
	QMessageBox::critical(this, "HTTP Error", error);
}

void MainWindow::on_actionNew_Account_Group_triggered()
{
	showCreateDialog();
}

void MainWindow::on_actionOpen_Account_Group_triggered()
{
	loadDatabase();
}

void MainWindow::on_tabWidget_currentChanged(int index)
{
	foreach(Tab* t, m_ui->tabWidget->findChildren<Tab*>())
	{
		t->flushData();
	}

	QWidget* current = m_ui->tabWidget->widget(index);
	Tab* tab = current->findChild<Tab*>();
	tab->updateContents();
}

void MainWindow::changeEvent(QEvent *e)
{
	QMainWindow::changeEvent(e);
	switch (e->type()) {
	case QEvent::LanguageChange:
		m_ui->retranslateUi(this);
		break;
	default:
		break;
	}
}
